package com.coursehub.shared.transaction;

import lombok.extern.slf4j.Slf4j;

/**
 * 抽象事务步骤基类
 * 提供通用的日志记录和异常处理功能
 */
@Slf4j
public abstract class AbstractTransactionStep implements TransactionStep {
    
    /**
     * 步骤名称
     */
    private final String stepName;
    
    /**
     * 步骤描述
     */
    private final String description;
    
    protected AbstractTransactionStep(String stepName) {
        this(stepName, stepName);
    }
    
    protected AbstractTransactionStep(String stepName, String description) {
        this.stepName = stepName;
        this.description = description;
    }
    
    @Override
    public String getStepName() {
        return stepName;
    }
    
    @Override
    public String getDescription() {
        return description;
    }
    
    @Override
    public final void execute() throws Exception {
        log.info("开始执行事务步骤: {} - {}", stepName, description);
        
        try {
            if (!canExecute()) {
                log.warn("事务步骤不满足执行条件: {}", stepName);
                throw new IllegalStateException("事务步骤不满足执行条件: " + stepName);
            }
            
            doExecute();
            log.info("事务步骤执行成功: {}", stepName);
            
        } catch (Exception e) {
            log.error("事务步骤执行失败: {} - {}", stepName, e.getMessage(), e);
            throw e;
        }
    }
    
    @Override
    public final void compensate() throws Exception {
        if (!needsCompensation()) {
            log.info("事务步骤无需补偿: {}", stepName);
            return;
        }
        
        log.info("开始补偿事务步骤: {} - {}", stepName, description);
        
        try {
            doCompensate();
            log.info("事务步骤补偿成功: {}", stepName);
            
        } catch (Exception e) {
            log.error("事务步骤补偿失败: {} - {}", stepName, e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 执行具体的业务逻辑
     * 子类需要实现此方法
     */
    protected abstract void doExecute() throws Exception;
    
    /**
     * 执行具体的补偿逻辑
     * 子类需要实现此方法
     */
    protected abstract void doCompensate() throws Exception;
    
    /**
     * 记录执行前的状态
     * 子类可以重写此方法来保存执行前的状态，用于补偿
     */
    protected void saveExecutionState() {
        // 默认实现为空，子类可以重写
    }
    
    /**
     * 清理执行状态
     * 子类可以重写此方法来清理保存的状态
     */
    protected void clearExecutionState() {
        // 默认实现为空，子类可以重写
    }
    
    @Override
    public String toString() {
        return String.format("%s{stepName='%s', description='%s'}", 
                getClass().getSimpleName(), stepName, description);
    }
}